package com.service.image;

import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.pub.dbo.constant.Global;
import com.service.pub.ConfigureServices;
import com.service.pub.ParameterFilter;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.spi.HttpServerProvider;



public class ImageService extends ConfigureServices implements Global
{
	private static int port;			// defauult : 8426;
	
	private static int threadMinCount; 	// default : 100;
	private static int threadMaxCount;	// default : 200;
	private static int checkPeriod;		//	default : 2;
	
	private static int imgCacheSize;	//	default : 50000;
	
	private static String context;		// default : /ImageService
	private static String imageRootPath;// image root path
	
	private static String imageTmpPath;// image tmp path
	
	private static Logger logger;

	static
	{
		logger 	= Logger.getLogger (ImageService.class.getName());
	}

	/**
	 * 
	 */
	public ImageService() 
	{
		super(ImageService.class.getSimpleName());
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		ImageService service = new ImageService();
		if(service.init()){
			service.handle();
		}else{
			System.out.println("parameter errer. Useage : xx.sh");
		}
			
	}
	
	public boolean init()
	{
		boolean isReturn = true;
		
		if(isReturn && configureFile.getValue("THREAD_COUNT_MIN") == null || configureFile.getValue("THREAD_COUNT_MIN").trim().equals("") || !configureFile.getValue("THREAD_COUNT_MIN").trim().matches("[\\d]+")){
  			logger.warn("can't find THREAD_COUNT_MIN property in configs.");
			isReturn = false;
    	}else{
    		threadMinCount = Integer.parseInt(configureFile.getValue("THREAD_COUNT_MIN").trim());
		}
		
		if(isReturn && configureFile.getValue("THREAD_COUNT_MAX") == null || configureFile.getValue("THREAD_COUNT_MAX").trim().equals("") || !configureFile.getValue("THREAD_COUNT_MAX").trim().matches("[\\d]+")){
  			logger.warn("can't find THREAD_COUNT_MAX property in configs.");
			isReturn = false;
    	}else{
    		threadMaxCount = Integer.parseInt(configureFile.getValue("THREAD_COUNT_MAX").trim());
		}
		
		if(isReturn && configureFile.getValue("PORT") == null || configureFile.getValue("PORT").trim().equals("") || !configureFile.getValue("PORT").trim().matches("[\\d]+")){
  			logger.warn("can't find PORT property in configs.");
			isReturn = false;
    	}else{
    		port = Integer.parseInt(configureFile.getValue("PORT").trim());
		}
		
		if(isReturn && configureFile.getValue("CHECK_PERIOD") == null || configureFile.getValue("CHECK_PERIOD").trim().equals("") || !configureFile.getValue("CHECK_PERIOD").trim().matches("[\\d]+")){
  			logger.warn("can't find CHECK_PERIOD property in configs.");
			isReturn = false;
    	}else{
    		checkPeriod = Integer.parseInt(configureFile.getValue("CHECK_PERIOD").trim());
		}
		
		if(isReturn && configureFile.getValue("CONTEXT") == null || configureFile.getValue("CONTEXT").trim().equals("")){
  			logger.warn("can't find CONTEXT property in configs.");
			isReturn = false;
    	}else{
    		context = configureFile.getValue("CONTEXT").trim();
		}
		
		if(isReturn && configureFile.getValue("IMAGE_ROOT_PATH") == null || configureFile.getValue("IMAGE_ROOT_PATH").trim().equals("")){
  			logger.warn("can't find IMAGE_ROOT_PATH property in configs.");
			isReturn = false;
    	}else{
    		imageRootPath = configureFile.getValue("IMAGE_ROOT_PATH").trim();
		}
		
		if(isReturn && configureFile.getValue("IMAGE_TMP_PATH") == null || configureFile.getValue("IMAGE_TMP_PATH").trim().equals("")){
  			logger.warn("can't find IMAGE_TMP_PATH property in configs.");
			isReturn = false;
    	}else{
    		imageTmpPath = configureFile.getValue("IMAGE_TMP_PATH").trim();
		}
		
		if(isReturn && configureFile.getValue("IMAGE_CACHE_SIZE") == null || configureFile.getValue("IMAGE_CACHE_SIZE").trim().equals("") || !configureFile.getValue("IMAGE_CACHE_SIZE").trim().matches("[\\d]+")){
  			logger.warn("can't find IMAGE_CACHE_SIZE property in configs.");
			isReturn = false;
    	}else{
    		imgCacheSize = Integer.parseInt(configureFile.getValue("IMAGE_CACHE_SIZE").trim());
		}
		
		
		return isReturn;
	}
	
	@SuppressWarnings("unchecked")
	public void handle()
	{
		HttpServerProvider httpServerProvider = HttpServerProvider.provider();  
       
		InetSocketAddress addr 			= null;
        HttpServer httpServer 			= null;
        
        ImageHttpHandler imageHandler 	= null;
        
        try {
        	ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadMinCount, threadMaxCount, checkPeriod, TimeUnit.SECONDS, new ArrayBlockingQueue(100), new ThreadPoolExecutor.CallerRunsPolicy()); 
             
            addr 			= new InetSocketAddress(port);
            imageHandler 	= new ImageHttpHandler(imageRootPath, imgCacheSize);
            
            imageHandler.setImageTmpDIR(imageTmpPath);
            
            httpServer = httpServerProvider.createHttpServer(addr, 1);  
            HttpContext httpContext = httpServer.createContext(context, imageHandler);  
            httpContext.getFilters().add(new ParameterFilter());
            
            httpServer.setExecutor(threadPool);  
            httpServer.start();
            
        } catch (Exception e) {  
            e.printStackTrace();  
        }
	}
}